package net.wanglu.www.zzz.rule.sva;

import java.util.HashMap;
import java.util.regex.Pattern;

import net.wanglu.www.zzz.rule.BadEgg;
import net.wanglu.www.zzz.rule.Rule;
import net.wanglu.www.zzz.service.se.nsubj._NSubjTuple;
import edu.stanford.nlp.trees.TreeGraphNode;

public class EndWithSAsSubj extends _SvaRule {

	public static final Pattern NewsSummons = Pattern.compile("\\bnews\\b|\\bmaths\\b|\\bworks\\b|\\bmeans\\b|\\bsummons\\b|\\btaps\\b|\\bwages\\b", Pattern.CASE_INSENSITIVE);
	public static final Pattern GamesS = Pattern.compile("\\bbilliards\\b|\\bdominoes\\b|\\bdarts\\b|\\bbowls\\b|\\bdraughts\\b|\\bcheckers\\b|\\bfives\\b|\\bskittles\\b|\\bninepins\\b|\\bnineholes\\b|\\bmusical chairs\\b|\\bmarbles\\b", Pattern.CASE_INSENSITIVE);
	public static final Pattern GamesP = Pattern.compile("\\cards\\b", Pattern.CASE_INSENSITIVE);
	public static final Pattern DiseaseS = Pattern.compile("\\bvives\\b|\\bstaggers\\b|\\bschistosomiasis\\b|\\bphlebitis\\b|\\bmulligrubs\\b|\\bhysterics\\b|\\bheaves\\b|\\bdiabetes\\b|\\bbronchitis\\b|\\bAIDS\\b|\\bmeasles\\b|\\bhives\\b|\\bpiles\\b|\\brabies\\b|\\bglanders\\b|\\bshingles\\b|\\barthritis\\b|\\bgripes\\b|\\bbends\\b", Pattern.CASE_INSENSITIVE);
	public static final Pattern DiseaseSP = Pattern.compile("\\bmumps\\b|\\brickets\\b", Pattern.CASE_INSENSITIVE);

	public final int NewsSummonsFlag = 1;
	public final int GamesSFlag = 2;
	public final int GamesPFlag = 3;
	public final int DiseaseSFlag = 4;
	public final int DiseaseSPFlag = 5;

	@Override
	public Object applicable(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		if ( super.applicable(objects) == Rule.Inapplicable) return Rule.Inapplicable;
		_NSubjTuple nst = (_NSubjTuple) objects[1];
		if ( !"NP".equals(nst.getSubjectAncestor().value())) return Rule.Inapplicable;
		return Rule.Applicable;
	}

	@Override
	public Object deviseRightSolution(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object examine(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		HashMap<?, ?> preprocessData = (HashMap<?, ?>) objects[0];
		_NSubjTuple nst =  (_NSubjTuple) objects[1];
		
		if ( this.applicable(preprocessData, nst) == Rule.Inapplicable) return Rule.Inapplicable;
		TreeGraphNode subj = (TreeGraphNode) nst.getSubj();
		TreeGraphNode verb = (TreeGraphNode) nst.getVerb();
		TreeGraphNode cop = (TreeGraphNode) nst.getCop();
		TreeGraphNode closestAux = (TreeGraphNode) nst.getAux();
		
		TreeGraphNode pred = verb;
		if ( cop != null) pred = cop;
		if ( closestAux != null) pred = closestAux;
		String predWord = pred.label().word();
		String predTag = pred.label().tag();

		if ( EndWithSAsSubj.NewsSummons.matcher(subj.label().word()).find()) {
			if (Rule.SingularVerb.matcher(predTag).find() && !"were".equals(predWord)) {
				return null;
			} else {
				BadEgg egg = new BadEgg();
				egg.setFlag(this.NewsSummonsFlag);
				egg.setProperty(BadEgg.Error);
				egg.setViolatedRule(this);
				egg.whereIsWrong = nst;
				return egg;
			}			
		} else if ( EndWithSAsSubj.GamesS.matcher(subj.label().word()).find()) {
			if (Rule.SingularVerb.matcher(predTag).find() && !"were".equals(predWord)) {
				return null;
			} else {
				BadEgg egg = new BadEgg();
				egg.setFlag(this.GamesSFlag);
				egg.setProperty(BadEgg.Error);
				egg.setViolatedRule(this);
				egg.whereIsWrong = nst;
				return egg;
			}						
		} else if ( EndWithSAsSubj.GamesP.matcher(subj.label().word()).find()) {
			if (Rule.PluralVerb.matcher(predTag).find() && !"was".equals(predWord)) {
				return null;
			} else {
				BadEgg egg = new BadEgg();
				egg.setFlag(this.GamesPFlag);
				egg.setProperty(BadEgg.Error);
				egg.setViolatedRule(this);
				egg.whereIsWrong = nst;
				return egg;
			}											
		} else if ( EndWithSAsSubj.DiseaseS.matcher(subj.label().word()).find()) {
			if (Rule.SingularVerb.matcher(predTag).find() && !"were".equals(predWord)) {
				return null;
			} else {
				BadEgg egg = new BadEgg();
				egg.setFlag(this.DiseaseSFlag);
				egg.setProperty(BadEgg.Error);
				egg.setViolatedRule(this);
				egg.whereIsWrong = nst;
				return egg;
			}						
		} else if ( EndWithSAsSubj.DiseaseSP.matcher(subj.label().word()).find()) {
			return null;
		}
		return Rule.Inapplicable;
	}
	@Override
	public Object whyItsWrong(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		BadEgg egg = (BadEgg) objects[0];
		sb.clear();
		switch(egg.getFlag()){
		case NewsSummonsFlag:
			sb.append("<p>");
			sb.append("有些名词以s结尾，但并无复数意义，作主语时谓语动词须用单数。如：news，maths，works，means，summons，taps，wages。");
			sb.append("The news on TV is always depressing.");
			sb.append("<br>");
			sb.append("News of victories keeps pouring in.");
			sb.append("<br>");
			sb.append("A summons was given to him.");
			sb.append("</p>");
			break;
		case GamesSFlag:
			sb.append("<p>");
			sb.append("某些以s结尾表示球类或游戏的名词作主语，谓语动词一般采用单数形式。这类名词有：billiards，dominoes，darts，bowls，draughts，checkers，fives，skittles，ninepins，nineholes，musical chairs，marbles，cards，谓语动词用单数.");
			sb.append("<br>");
			sb.append("例如：");
			sb.append("<br>");
			sb.append("Billards is played by women as well as men.");
			sb.append("<br>");
			sb.append("Billiards is a good indoor game.");
			sb.append("<br>");
			sb.append("Dominoes is played with 28 flat, oblong pieces of bone or wood.");
			sb.append("<br>");
			sb.append("Hearts is an interesting game.");
			sb.append("<br>");
			sb.append("Rackets is played in a walled court.");
			sb.append("</p>");
			break;
		case GamesPFlag:
			sb.append("<p>");
			sb.append("个别游戏名称要与复数谓语一直。例如：");
			sb.append("<br>");
			sb.append("Cards are played everywhere in China.");
			sb.append("</p>");
			break;
		case DiseaseSFlag:
			sb.append("<p>");
			sb.append("某些以s结尾表示疾病名称的名词作主语时,谓语动词用单数.如:measles,hives,rickets,piles,mumps,rabies,glanders,shingles,arthritis,gripes,the bends.");
			sb.append("<br>");
			sb.append("Measles takes a long time to get over.");
			sb.append("<br>");
			sb.append("注意：有些疾病也有人把它们当复数看。例如：");
			sb.append("<br>");
			sb.append("Mumps are/is fairly rare in adults.");
			sb.append("<br>");
			sb.append("Rickets is/are caused by malnutrition.");
			sb.append("</p>");
			break;
		default:
			return null;
		}
		return sb.toString();
	}
}
